<template>
  <div class="real-time-data-container">
    <div class="search-box">
      <form action="/">
        <van-search
          v-model="searchKey"
          shape="round"
          placeholder="搜索变量名"
          clearable
          @search="filterFn"
          @clear="clearFilterFn"
        />
      </form>
    </div>

    <ul
      class="data-list scroll-box"
      v-if="filterRealTimeData.length"
    >
      <template v-for="(item, index) in filterRealTimeData">
        <li
          :key="index"
          v-if="item.varibleAuthority !== 3"
        >
          <p class="data-name">{{ item.vname }}</p>
          <p class="data-value">
            <span>{{ item.val !== undefined ? item.val : '-' }}</span>
            {{ item.vcompany }}
          </p>
          <div class="data-type-control">
            <span class="color-gray">类型：{{ item.vtype }}</span>
            <span
              class="color-primary"
              v-if="item.varibleAuthority === 1 && item.vjurisdiction === 1"
              @click="showControlFn(item)"
            >远程控制</span>
          </div>
        </li>
      </template>
    </ul>

    <div
      class="no-data-box"
      v-else
    >暂无数据</div>

    <!-- 选择变量 -->
    <div class="opearte-box">
      <div
        class="operate-btn"
        @click="openChooseVar"
      >选择变量</div>
    </div>

    <!-- 远程控制 -->
    <van-popup v-model="showControl">
      <div class="control-box">
        <p class="title">远程控制</p>
        <ul class="content-box">
          <li>
            <p>变量名</p>
            <van-field
              v-model="varName"
              readonly
            />
          </li>
          <li v-if="varType === 'Bool'">
            <p>
              <i class="color-red">*</i>
              变量值
            </p>
            <div
              class="li-content"
              @click="showSheet = true"
            >
              <van-field
                v-model="varBoolean"
                readonly
                placeholder="请选择"
              />
              <van-icon name="arrow" />
            </div>
          </li>
          <li v-else>
            <p>
              <i class="color-red">*</i>
              变量值
            </p>
            <van-field
              v-model="varValue"
              placeholder="请输入"
            />
          </li>
          <li v-if="$route.query.controlPwd">
            <p>
              <i class="color-red">*</i>
              设备控制密码
            </p>
            <van-field
              v-model="varPassword"
              placeholder="请输入"
            />
          </li>
        </ul>
        <ul class="operate-box">
          <li @click="cancelFn">取消</li>
          <li
            class="color-primary"
            @click="submitControl"
          >确定</li>
        </ul>
      </div>
    </van-popup>

    <!-- 布尔类型值设置 -->
    <van-action-sheet
      v-model="showSheet"
      :actions="actions"
      cancel-text="取消"
      description="变量值"
      @select="onSelect"
    />

    <!-- 变量选择 -->
    <van-popup
      v-model="showVarBox"
      position="bottom"
      :style="{ height: '64%' }"
    >
      <div class="var-box">
        <div class="var-box-header">
          <span class="model-name">{{ $route.query.deviceName || '' }}</span>
          <p class="model-choose">已选择（<span class="color-primary">{{ chooseVarData.length }}</span>/{{ varList.length || 0 }}）</p>
        </div>
        <div class="var-search-box">
          <van-search
            v-model="searchKeyForVar"
            shape="round"
            placeholder="输入变量名称查找"
            clearable
            @search="handleSearch"
            @clear="handleClear"
          />
        </div>
        <ul class="var-list scroll-box">
          <li
            v-for="item in filterVarList"
            :key="item.vname"
            :class="{'color-primary': item.checked}"
            @click="selectVar(item)"
          >
            <span>{{ item.vname }}</span>
            <van-icon
              name="success"
              v-if="item.checked"
            />
          </li>
        </ul>
        <ul class="operate-box">
          <li @click="cancelSelect">取消</li>
          <li
            class="color-primary"
            @click="confirmSelect"
          >确定</li>
        </ul>
      </div>
    </van-popup>
  </div>
</template>

<script>
import { Search, Popup, Field, ActionSheet, Icon } from 'vant';
import { getModelVariable, getDeviceVariable, parameterDownload, addDeviceVariable } from '@/api/deviceManage.js';

export default {
  name: 'RealTimeData',
  components: {
    [Search.name]: Search,
    [Popup.name]: Popup,
    [Field.name]: Field,
    [ActionSheet.name]: ActionSheet,
    [Icon.name]: Icon
  },
  inject: ['parent'],
  data() {
    return {
      searchKey: '',
      showControl: false,
      varName: '',
      varValue: '',
      varBoolean: '',
      varType: '',
      varPassword: '',
      varKey: '',
      showVarBox: false,
      deviceData: [],
      filterRealTimeData: [],
      socket: '',
      showSheet: false,
      actions: [
        { name: '0', value: 0 },
        { name: '1', value: 1 }
      ],
      searchKeyForVar: '',
      varTotal: 0,
      varList: [],
      filterVarList: [],
      deviceModelId: '',
      deviceModelName: '',
      chooseVarData: []
    };
  },
  created() {
    console.log('RealTimeData');
    this.getModelVariable();
  },
  mounted() {
    // this.socket = this.parent.socket;
    this.getDeviceVariable();
  },
  methods: {
    // 获取物模型变量
    getModelVariable() {
      getModelVariable({
        id: this.$route.query.modelId
      }).then(res => {
        this.varList = res.data || [];
        this.varList.map(item => {
          item.checked = false;
        });
        this.filterVarList = JSON.parse(JSON.stringify(this.varList));
      });
    },
    // 获取设备变量
    getDeviceVariable() {
      getDeviceVariable({
        id: this.$route.query.id
      })
        .then(res => {
          let data = res.data || [];
          this.deviceData = data;
          this.filterRealTimeData = data;
        })
        .then(() => {
          this.websocketFn();
        });
    },
    // 筛选数据
    filterFn() {
      let filterArr = this.deviceData.filter(item => {
        return item.vname.indexOf(this.searchKey) !== -1;
      });
      this.filterRealTimeData = filterArr;
    },
    // 清除数据筛选
    clearFilterFn() {
      this.filterRealTimeData = JSON.parse(JSON.stringify(this.deviceData));
    },
    // websocket
    websocketFn() {
      const param = {
        device_id: this.$route.query.id,
        product_id: this.$route.query.modelId,
        type: 2,
        is_single: true //是否单独监听此设备， 若为true 则客户端只会监听此设备
      };
      if (this.socket) {
        this.socket.send(JSON.stringify(param));
      } else {
        let token = localStorage.getItem('token');
        this.socket = new WebSocket(`ws://${location.host}/base/iot_websocket/ws/`, [token]);
        this.socket.onopen = res => {
          this.socket.send(JSON.stringify(param));
        };
      }

      this.socket.onmessage = res => {
        if (res.data) {
          const temp = [];
          const data = JSON.parse(res.data);
          const points = data.Record ? data.Record.Points : [];
          this.filterRealTimeData.forEach(real => {
            points.forEach(item => {
              if (real.vk === item.K) {
                real.val = item.V;
              }
            });
            temp.push(real);
          });

          if (this.searchKey) {
            this.filterFn();
          } else {
            this.filterRealTimeData = JSON.parse(JSON.stringify(temp));
          }
        }
      };

      this.socket.onclose = res => {
        console.log('Connection closed.');
      };

      this.socket.onerror = () => {
        console.log('Connection error');
      };
    },
    // 显示远程控制
    showControlFn(item) {
      this.varName = item.vname;
      this.varType = item.vtype;
      this.varKey = item.vk;
      this.showControl = true;
    },
    // 取消远程控制
    cancelFn() {
      this.showControl = false;
      this.varName = '';
      this.varType = '';
      this.varKey = '';
      this.varValue = '';
      this.varBoolean = '';
      this.varPassword = '';
    },
    // 远程控制变量值选项
    onSelect(item) {
      this.varBoolean = item.value;
      this.showSheet = false;
    },
    // 提交远程控制
    submitControl() {
      if (this.varPassword !== this.$route.query.controlPwd) {
        this.$toast('设备控制密码错误');
      } else {
        let value = '';
        if (this.varType === 'Bool') {
          value = this.varBoolean;
        } else {
          value = this.varValue;
        }

        switch (this.varType) {
          case 'UInt8':
            value = parseInt(value);
            break;
          case 'UInt32':
            value = parseInt(value);
            break;
          case 'Int32':
            value = parseInt(value);
            break;
          case 'UInt16':
            value = parseInt(value);
            break;
          case 'Int16':
            value = parseInt(value);
            break;
          case 'Int8':
            value = parseInt(value);
            break;
          case 'Bool':
            value = parseInt(value);
            break;
          case 'Real':
            value = parseFloat(value);
            break;
          case 'String':
            value = String(value);
            break;
        }

        let point = {
          K: this.varKey,
          V: value
        };
        let deviceId = parseInt(this.$route.query.id);
        let password = this.varPassword;

        let params = {
          device_id: deviceId,
          password,
          points: point
        };

        parameterDownload(params).then(res => {
          this.$toast({
            message: '操作成功',
            duration: 1200,
            onClose: () => {
              this.cancelFn();
            }
          });
        });
      }
    },
    // 打开选择变量
    openChooseVar() {
      if (this.chooseVarData.length) {
        this.chooseVarData.map(item => {
          this.filterVarList.map(subItem => {
            if (item.vname === subItem.vname) {
              subItem.checked = true;
            }
          });
        });
      }
      this.showVarBox = true;
    },
    // 搜索变量
    handleSearch() {
      let filterArr = this.varList.filter(item => {
        return item.vname.indexOf(this.searchKeyForVar) !== -1;
      });
      this.filterVarList = filterArr;
    },
    // 清空搜索
    handleClear() {
      this.filterVarList = this.varList;
    },
    // 选择变量
    selectVar(item) {
      item.checked = !item.checked;
      this.$forceUpdate();
      if (item.checked) {
        this.chooseVarData.push(item);
      } else {
        this.chooseVarData.map((v, i) => {
          if (v.vname === item.vname) {
            this.chooseVarData.splice(i, 1);
          }
        });
      }
    },
    // 取消变量选择
    cancelSelect() {
      this.showVarBox = false;
    },
    // 确定变量选择
    confirmSelect() {
      let list = [];
      this.chooseVarData.map(item => {
        list.push({
          varibleAuthority: item.varibleAuthority,
          vcompany: item.vcompany,
          vjurisdiction: item.vjurisdiction,
          vk: item.vk,
          vname: item.vname,
          vtype: item.vtype
        });
      });

      addDeviceVariable({
        deviceId: this.$route.query.id,
        list,
        modelId: this.$route.query.modelId
      }).then(res => {
        this.filterRealTimeData = [];
        this.getDeviceVariable();
      });

      this.showVarBox = false;
    }
  },
  beforeDestroy() {
    if (this.socket) {
      this.socket.close();
      this.socket = null;
    }
  }
};
</script>

<style lang="scss" scoped>
.real-time-data-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;

  .search-box {
    flex-shrink: 0;
  }

  .data-list {
    flex: 1;
    padding-top: 0.213333rem;

    li {
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      width: 4.88rem;
      height: 2.666667rem;
      margin-bottom: 0.213333rem;
      padding: 0.32rem;
      background-color: #fff;

      &:nth-of-type(odd) {
        float: left;
      }

      &:nth-of-type(even) {
        float: right;
      }

      .data-name {
        font-size: 0.32rem;
        color: var(--color-primary);
        text-align: center;
      }

      .data-value {
        font-size: 0.346667rem;
        color: var(--color-gray);
        text-align: center;

        span {
          color: var(--color-black);
          font-size: 0.426667rem;
        }
      }

      .data-type-control {
        display: flex;
        justify-content: space-between;
        align-items: center;

        span {
          &:first-of-type {
            font-size: 0.266667rem;
          }
          &:last-of-type {
            font-size: 0.32rem;
          }
        }
      }
    }
  }

  .no-data-box {
    flex: 1;
    padding: 0.32rem 0.426667rem;
    text-align: center;
    color: var(--color-gray);
    font-size: 0.373333rem;
  }

  .opearte-box {
    flex-shrink: 0;
    width: 100%;
    height: 1.493333rem;
    padding: 0.213333rem 0.426667rem;
    background-color: #fff;

    .operate-btn {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 100%;
      height: 100%;
      border: 1px solid var(--color-primary);
      border-radius: 0.106667rem;
      color: var(--color-primary);
      font-size: 0.426667rem;
    }
  }

  .van-popup--center {
    border-radius: 0.426667rem;

    .control-box {
      display: flex;
      flex-direction: column;
      width: 8.32rem;
      height: 9.84rem;
      overflow: hidden;

      .title {
        flex-shrink: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 16px;
        padding: 0.426667rem;
        border-radius: 0.426667rem;
      }

      .content-box {
        flex: 1;
        padding: 0 0.426667rem;

        li {
          padding: 0.32rem 0;

          p {
            margin-bottom: 0.106667rem;
            color: var(--color-deep-gray);
            font-size: 0.32rem;
          }

          .van-field {
            padding-left: 0;
            font-size: 0.373333rem;

            ::v-deep .van-field__value {
              padding-bottom: 0.266667rem;
              border-bottom: 1px solid #f2f6fc;
            }

            &::after {
              border-bottom: 0 !important;
            }
          }

          .li-content {
            display: flex;
            justify-content: space-between;
            align-items: center;

            .van-icon {
              color: var(--color-gray);
              font-size: 0.373333rem;
            }
          }
        }
      }

      .operate-box {
        display: flex;
        width: 100%;
        height: 1.28rem;
        border-top: 1px solid var(--border-color);

        li {
          position: relative;
          display: flex;
          justify-content: center;
          align-items: center;
          width: 50%;
          font-size: 0.426667rem;

          &:first-of-type {
            &::after {
              content: '';
              position: absolute;
              top: 0;
              right: 0;
              width: 1px;
              height: 100%;
              background-color: var(--border-color);
            }
          }
        }
      }
    }
  }

  .van-popup--bottom {
    border-top-left-radius: 0.426667rem;
    border-top-right-radius: 0.426667rem;

    .var-box {
      display: flex;
      flex-direction: column;
      width: 100%;
      height: 100%;

      .var-box-header {
        flex-shrink: 0;
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 0.213333rem;
        padding: 0 0.426667rem;
        padding-top: 0.426667rem;

        .model-name {
          margin-right: 0.266667rem;
          font-size: 0.426667rem;
          line-height: 0.533333rem;
        }

        .model-choose {
          flex-shrink: 0;
          color: var(--color-deep-gary);
          font-size: 0.32rem;
        }
      }

      .var-search-box {
        flex-shrink: 0;
        margin-bottom: 0.213333rem;
        border-bottom: 1px solid var(--border-color);
      }

      .var-list {
        flex: 1;
        width: 100%;
        padding: 0 0.426667rem;

        li {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding: 0.32rem 0;
          font-size: 0.373333rem;
          border-bottom: 1px solid var(--border-color);

          &:last-of-type {
            border-bottom: 0;
          }
        }
      }

      .operate-box {
        flex-shrink: 0;
        display: flex;
        width: 100%;
        height: 1.28rem;
        border-top: 1px solid var(--border-color);

        li {
          position: relative;
          display: flex;
          justify-content: center;
          align-items: center;
          width: 50%;
          font-size: 0.426667rem;

          &:first-of-type {
            &::after {
              content: '';
              position: absolute;
              top: 0;
              right: 0;
              width: 1px;
              height: 100%;
              background-color: var(--border-color);
            }
          }
        }
      }
    }
  }
}
</style>